home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / game / shoot / ADescentSrc.lha / descent / main / texmerge.c < prev    next >
C/C++ Source or Header  |  1998-09-26  |  10KB  |  386 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: /usr/CVS/descent/main/texmerge.c,v $
  15.  * $Revision: 1.5 $
  16.  * $Author: nobody $
  17.  * $Date: 1998/09/26 15:11:54 $
  18.  * 
  19.  * Routines to cache merged textures.
  20.  * 
  21.  * $Log: texmerge.c,v $
  22.  * Revision 1.5  1998/09/26 15:11:54  nobody
  23.  * Added Warp3D support
  24.  *
  25.  * Revision 1.4  1998/03/22 15:41:05  hfrieden
  26.  * conflict resolved
  27.  *
  28.  * Revision 1.3  1998/03/22 15:26:38  tfrieden
  29.  * removed lots of warning messages
  30.  *
  31.  * Revision 1.2  1998/03/22 01:53:30  tfrieden
  32.  * Removed silly least_recently_used = 0
  33.  *
  34.  * Revision 1.1.1.1  1998/03/03 15:12:31  nobody
  35.  * reimport after crash from backup
  36.  *
  37.  * Revision 1.1.1.1  1998/02/13  20:20:58  hfrieden
  38.  * Initial Import
  39.  */
  40.  
  41. #pragma off (unreferenced)
  42. static char rcsid[] = "$Id: texmerge.c,v 1.5 1998/09/26 15:11:54 nobody Exp $";
  43. #pragma on (unreferenced)
  44.  
  45. #include <stdlib.h>
  46. #include <stdio.h>
  47.  
  48. #include "gr.h"
  49. #include "error.h"
  50. #include "game.h"
  51. #include "textures.h"
  52. #include "mono.h"
  53. #include "rle.h"
  54. #include "piggy.h"
  55.  
  56. #ifdef VIRGIN
  57. #include "VirgeTexture.h"
  58. #include "gauges.h"
  59. #endif
  60.  
  61. #define MAX_NUM_CACHE_BITMAPS 50
  62.  
  63. #ifdef DEBUG_PROFILE
  64. extern fix profile_mtn_time;
  65. extern fix profile_mtsx_time;
  66. extern int profile_mtn_called;
  67. extern int profile_mtsx_called;
  68. #endif
  69.  
  70. //static grs_bitmap * cache_bitmaps[MAX_NUM_CACHE_BITMAPS];                     
  71.  
  72. typedef struct  {
  73.     grs_bitmap * bitmap;
  74.     grs_bitmap * bottom_bmp;
  75.     grs_bitmap * top_bmp;
  76.     int         orient;
  77.     int     last_frame_used;
  78. } TEXTURE_CACHE;
  79.  
  80. static TEXTURE_CACHE Cache[MAX_NUM_CACHE_BITMAPS];
  81.  
  82. static int num_cache_entries = 0;
  83.  
  84. static int cache_hits = 0;
  85. static int cache_misses = 0;
  86.  
  87. void merge_textures_new( int type, grs_bitmap * bottom_bmp, grs_bitmap * top_bmp, ubyte * dest_data );
  88. void merge_textures_super_xparent( int type, grs_bitmap * bottom_bmp, grs_bitmap * top_bmp, ubyte * dest_data );
  89.  
  90.  
  91. void texmerge_close();
  92.  
  93. //----------------------------------------------------------------------
  94.  
  95. int texmerge_init(int num_cached_textures)
  96. {
  97.     int i;
  98.  
  99.     if ( num_cached_textures <= MAX_NUM_CACHE_BITMAPS )
  100.         num_cache_entries = num_cached_textures;
  101.     else
  102.         num_cache_entries = MAX_NUM_CACHE_BITMAPS;
  103.     
  104.     for (i=0; i<num_cache_entries; i++ )    {
  105.             // Make temp tmap for use when combining
  106.         Cache[i].bitmap = gr_create_bitmap( 64, 64 );
  107.  
  108.         //if (get_selector( Cache[i].bitmap->bm_data, 64*64,  &Cache[i].bitmap->bm_selector))
  109.         //  Error( "ERROR ALLOCATING CACHE BITMAP'S SELECTORS!!!!" );
  110.  
  111.         Cache[i].last_frame_used = -1;
  112.         Cache[i].top_bmp = NULL;
  113.         Cache[i].bottom_bmp = NULL;
  114.         Cache[i].orient = -1;
  115.     }
  116.     atexit( texmerge_close );
  117.  
  118.     return 1;
  119. }
  120.  
  121. void texmerge_flush()
  122. {
  123.     int i;
  124.  
  125.     for (i=0; i<num_cache_entries; i++ )    {
  126.     #ifdef VIRGIN
  127.         VirgeInvalidCacheEntry(Cache[i].bitmap);
  128.     #endif
  129.     #ifdef WARP3D
  130.         WARP_InvalidCacheEntry(Cache[i].bitmap);
  131.     #endif
  132.         Cache[i].last_frame_used = -1;
  133.         Cache[i].top_bmp = NULL;
  134.         Cache[i].bottom_bmp = NULL;
  135.         Cache[i].orient = -1;
  136.     }
  137. }
  138.  
  139.  
  140. //-------------------------------------------------------------------------
  141. void texmerge_close()
  142. {
  143.     int i;
  144.  
  145.     for (i=0; i<num_cache_entries; i++ )    {
  146.         gr_free_bitmap( Cache[i].bitmap );
  147.         Cache[i].bitmap = NULL;
  148.     }
  149. }
  150.  
  151. //--unused-- int info_printed = 0;
  152.  
  153. grs_bitmap * texmerge_get_cached_bitmap( int tmap_bottom, int tmap_top )
  154. {
  155.     grs_bitmap *bitmap_top, *bitmap_bottom;
  156.     int i, orient;
  157.     int lowest_frame_count;
  158.     int least_recently_used;
  159.  
  160. //  if ( ((FrameCount % 1000)==0) && ((cache_hits+cache_misses)>0) && (!info_printed) ) {
  161. //      mprintf( 0, "Texmap caching:  %d hits, %d misses. (Missed=%d%%)\n", cache_hits, cache_misses, (cache_misses*100)/(cache_hits+cache_misses)  );
  162. //      info_printed = 1;
  163. //  } else {
  164. //      info_printed = 0;
  165. //  }
  166.  
  167.     bitmap_top = &GameBitmaps[Textures[tmap_top&0x3FFF].index];
  168.     bitmap_bottom = &GameBitmaps[Textures[tmap_bottom].index];
  169.     
  170.     orient = ((tmap_top&0xC000)>>14) & 3;
  171.  
  172.     least_recently_used = 0;
  173.     lowest_frame_count = Cache[0].last_frame_used;
  174.     
  175.     for (i=0; i<num_cache_entries; i++ )    {
  176.         if ( (Cache[i].last_frame_used > -1) && (Cache[i].top_bmp==bitmap_top) && (Cache[i].bottom_bmp==bitmap_bottom) && (Cache[i].orient==orient ))   {
  177.             cache_hits++;
  178.             Cache[i].last_frame_used = FrameCount;
  179.             return Cache[i].bitmap;
  180.         }   
  181.         if ( Cache[i].last_frame_used < lowest_frame_count )    {
  182.             lowest_frame_count = Cache[i].last_frame_used;
  183.             least_recently_used = i;
  184.         }
  185.     }
  186.     
  187.     //---- Page out the LRU bitmap;
  188.     cache_misses++;
  189.  
  190.     // Make sure the bitmaps are paged in...
  191. #ifdef PIGGY_USE_PAGING
  192.     piggy_page_flushed = 0;
  193.  
  194.     PIGGY_PAGE_IN(Textures[tmap_top&0x3FFF]);
  195.     PIGGY_PAGE_IN(Textures[tmap_bottom]);
  196.     if (piggy_page_flushed) {
  197.         // If cache got flushed, re-read 'em.
  198.         piggy_page_flushed = 0;
  199.         PIGGY_PAGE_IN(Textures[tmap_top&0x3FFF]);
  200.         PIGGY_PAGE_IN(Textures[tmap_bottom]);
  201.     }
  202.     Assert( piggy_page_flushed == 0 );
  203. #endif
  204.  
  205.     if (bitmap_top->bm_flags & BM_FLAG_SUPER_TRANSPARENT)   {
  206.         merge_textures_super_xparent( orient, bitmap_bottom, bitmap_top, Cache[least_recently_used].bitmap->bm_data );
  207.         Cache[least_recently_used].bitmap->bm_flags = BM_FLAG_TRANSPARENT;
  208.         Cache[least_recently_used].bitmap->avg_color = bitmap_top->avg_color;
  209.     } else  {
  210.         merge_textures_new( orient, bitmap_bottom, bitmap_top, Cache[least_recently_used].bitmap->bm_data );
  211.         Cache[least_recently_used].bitmap->bm_flags = bitmap_bottom->bm_flags & (~BM_FLAG_RLE);
  212.         Cache[least_recently_used].bitmap->avg_color = bitmap_bottom->avg_color;
  213.     }
  214.         
  215.     Cache[least_recently_used].top_bmp = bitmap_top;
  216.     Cache[least_recently_used].bottom_bmp = bitmap_bottom;
  217.     Cache[least_recently_used].last_frame_used = FrameCount;
  218.     Cache[least_recently_used].orient = orient;
  219. #ifdef VIRGIN
  220.     VirgeInvalidCacheEntry(Cache[least_recently_used].bitmap);
  221. #endif
  222. #ifdef WARP3D
  223.     WARP_InvalidCacheEntry(Cache[least_recently_used].bitmap);
  224. #endif
  225.     return Cache[least_recently_used].bitmap;
  226. }
  227.  
  228. void merge_textures_new( int type, grs_bitmap * bottom_bmp, grs_bitmap * top_bmp, ubyte * dest_data )
  229. {
  230.     ubyte c;
  231.     int x,y;
  232.     ubyte * top_data, *bottom_data;
  233. #ifdef DEBUG_PROFILE
  234.     fix start_time = timer_get_fixed_seconds();
  235.     profile_mtn_called++;
  236. #endif
  237.  
  238.     if ( top_bmp->bm_flags & BM_FLAG_RLE )
  239.         top_bmp = rle_expand_texture(top_bmp);
  240.  
  241.     if ( bottom_bmp->bm_flags & BM_FLAG_RLE )
  242.         bottom_bmp = rle_expand_texture(bottom_bmp);
  243.  
  244. //  Assert( bottom_bmp != top_bmp );
  245.  
  246.     top_data = top_bmp->bm_data;
  247.     bottom_data = bottom_bmp->bm_data;
  248.  
  249. //  Assert( bottom_data != top_data );
  250.  
  251.     // mprintf( 0, "Type=%d\n", type );
  252.  
  253.     switch( type )  {
  254.         case 0:
  255.             // Normal
  256.             // gr_merge_textures( bottom_data, top_data, dest_data );
  257.             for (y=0;y<64;y++) for (x=0;x<64;x++) {
  258.                 c=top_data[64*y+x];
  259.                 if (c==TRANSPARENCY_COLOR)
  260.                     c=bottom_data[64*y+x];
  261.                 *dest_data++=c;
  262.             }
  263.             break;
  264.         case 1:
  265.             // gr_merge_textures_1( bottom_data, top_data, dest_data );
  266.  
  267.             for (y=0; y<64; y++ )
  268.                 for (x=0; x<64; x++ )   {
  269.                     c = top_data[ 64*x+(63-y) ];        
  270.                     if (c==TRANSPARENCY_COLOR)
  271.                         c = bottom_data[ 64*y+x ];
  272.                     *dest_data++ = c;
  273.                 }
  274.             break;
  275.         case 2:
  276.             // gr_merge_textures_2( bottom_data, top_data, dest_data );
  277.             for (y=0; y<64; y++ )
  278.                 for (x=0; x<64; x++ )   {
  279.                     c = top_data[ 64*(63-y)+(63-x) ];
  280.                     if (c==TRANSPARENCY_COLOR)
  281.                         c = bottom_data[ 64*y+x ];
  282.                     *dest_data++ = c;
  283.                 }
  284.             break;
  285.         case 3:
  286.             // gr_merge_textures_3( bottom_data, top_data, dest_data );
  287.             for (y=0; y<64; y++ )
  288.                 for (x=0; x<64; x++ )   {
  289.                     c = top_data[ 64*(63-x)+y  ];
  290.                     if (c==TRANSPARENCY_COLOR)
  291.                         c = bottom_data[ 64*y+x ];
  292.                     *dest_data++ = c;
  293.                 }
  294.             break;
  295.     }
  296.  
  297. #ifdef DEBUG_PROFILE
  298.     profile_mtn_time += timer_get_fixed_seconds() - start_time;
  299. #endif
  300.  
  301. }
  302.  
  303. void merge_textures_super_xparent( int type, grs_bitmap * bottom_bmp, grs_bitmap * top_bmp, ubyte * dest_data )
  304. {
  305.     ubyte c;
  306.     int x,y;
  307.     ubyte * top_data, *bottom_data;
  308. #ifdef DEBUG_PROFILE
  309.     fix start_time = timer_get_fixed_seconds();
  310.     profile_mtsx_called++;
  311. #endif
  312.  
  313.  
  314.     if ( top_bmp->bm_flags & BM_FLAG_RLE )
  315.         top_bmp = rle_expand_texture(top_bmp);
  316.  
  317.     if ( bottom_bmp->bm_flags & BM_FLAG_RLE )
  318.         bottom_bmp = rle_expand_texture(bottom_bmp);
  319.  
  320. //  Assert( bottom_bmp != top_bmp );
  321.  
  322.     top_data = top_bmp->bm_data;
  323.     bottom_data = bottom_bmp->bm_data;
  324.  
  325. //  Assert( bottom_data != top_data );
  326.  
  327.     //mprintf( 0, "SuperX remapping type=%d\n", type );
  328.     //Int3();
  329.      
  330.     switch( type )  {
  331.         case 0:
  332.             // Normal
  333.             for (y=0; y<64; y++ )
  334.                 for (x=0; x<64; x++ )   {
  335.                     c = top_data[ 64*y+x ];     
  336.                     if (c==TRANSPARENCY_COLOR)
  337.                         c = bottom_data[ 64*y+x ];
  338.                     else if (c==254)
  339.                         c = TRANSPARENCY_COLOR;
  340.                     *dest_data++ = c;
  341.                 }
  342.             break;
  343.         case 1:
  344.             // 
  345.             for (y=0; y<64; y++ )
  346.                 for (x=0; x<64; x++ )   {
  347.                     c = top_data[ 64*x+(63-y) ];        
  348.                     if (c==TRANSPARENCY_COLOR)
  349.                         c = bottom_data[ 64*y+x ];
  350.                     else if (c==254)
  351.                         c = TRANSPARENCY_COLOR;
  352.                     *dest_data++ = c;
  353.                 }
  354.             break;
  355.         case 2:
  356.             // Normal
  357.             for (y=0; y<64; y++ )
  358.                 for (x=0; x<64; x++ )   {
  359.                     c = top_data[ 64*(63-y)+(63-x) ];
  360.                     if (c==TRANSPARENCY_COLOR)
  361.                         c = bottom_data[ 64*y+x ];
  362.                     else if (c==254)
  363.                         c = TRANSPARENCY_COLOR;
  364.                     *dest_data++ = c;
  365.                 }
  366.             break;
  367.         case 3:
  368.             // Normal
  369.             for (y=0; y<64; y++ )
  370.                 for (x=0; x<64; x++ )   {
  371.                     c = top_data[ 64*(63-x)+y  ];
  372.                     if (c==TRANSPARENCY_COLOR)
  373.                         c = bottom_data[ 64*y+x ];
  374.                     else if (c==254)
  375.                         c = TRANSPARENCY_COLOR;
  376.                     *dest_data++ = c;
  377.                 }
  378.             break;
  379.     }
  380.  
  381. #ifdef DEBUG_PROFILE
  382.     profile_mtsx_time += timer_get_fixed_seconds() - start_time;
  383. #endif
  384.  
  385. }
  386.